package com.jinken.utils;

import org.jose4j.json.JsonUtil;
import org.jose4j.jwa.AlgorithmConstraints;
import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.InvalidJwtException;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.lang.JoseException;

import java.security.PrivateKey;
import java.security.PublicKey;

public class JwtUtils {




    // 私钥
    public final static    String privatejson  = "{\"kty\":\"RSA\",\"n\":\"3O_svMpJzjAcp6vb56bXiE5g8xP1g-qssy3U11SCzWD7MxL0qx0XijUbicwRJKiozVKz1gs-E_EhFwKQPob-gRmMwJ5N6vCQcDLI7QXaZchJl9Zy_VSfFo2x5qnMVdR-AIOqMu8MROcI3z0xvZnhJGju4TI_Ka1XrUQTB_75MUxnW-bJCKubQDreLPfvqdeWkxEjsXrHB2X5JtvYgp0jz9ONuBBYm13MiShla5VgOkFNH7okg26leHKuPlPOs3MtdEbeHTOxw5qlIl7BEoXoNehk_Iu5K7hjQ5BwmV9aRG1V9B_eWfGJ3dsF2yjoevS0Fr6ckoaicIkjaisSZ5aPqQ\",\"e\":\"AQAB\",\"d\":\"KoSowldKt1m2dgUio5TN5z8wNK9rYQj1VeE01ADBUG2Awj48ZD7LxC7-vvjM9slXfPYUwlU1C-jsdY1qfYIEsgsc9YexloxXu6PmW4j0FADkusoMJJkXqaM4sJuORZlIa2hrRXSQH6V3pWCVNTgLJjLkf-Wn1qkzlZZjdDc7NSNzqb0csh6HUDT08ecd63HL75Z-VZ3JRJNEmvKACs9buqvH0XGspQeJY0YNebiUTZjtOZkmsFjnat8n-okeZXIZAqut9AfTYDsMOlpjwNd47YgzSy79FOQ6Xgn2aZw2cprOju5TLPymOURp1hNtybTIjBbDfW7uOyAvyXnlEYi8JQ\",\"p\":\"9ugjC5KIsmihs1BITkFJc7z5wRdv6_MmRNbsAUvsS7srbkRtQfGJNiJRZ-BzyZ2ODFPPVxArU7fAda8DfrOVZ9zz0ytkanpGQTm3faicGsG2VtPf73A2beO0eKpTEyV0j1Iu7N8E5RfHAhqqva5atRW0g5jwk2qgVZLM5EwBrr0\",\"q\":\"5RLxplkKQ69Y9m-Vo0ZJy8q1-Q5v8NidB5WaAw-CD-TN_Q16j_QSHJGG8kM1zet54U96u6OXCC2SWfnj2RBK17JBb-GCkKqp83tROWRgqRsLmYfOSzlnMNDlSoyTeYdtyfthYqycmGTRn68xnKv7Tae_nlecpvC1yE1A3ol6OV0\",\"dp\":\"C0PABZEj52_aoMGy6s8TuNIQWvzkwFERl-ZuUgjSuQnLC3bXvUB10CB0slaNMc-cYXeZaBF2yJUDlNrtP-SVlm2AOkwqgqkdd3BYrMT6ikX4ObHk75mhAhZ3b2Hl9GOrE7beKTRrlsAk9jWdQJYp0UUyPSbHIxKkSgMukePd18k\",\"dq\":\"4Y3fpt2xf6fePvjsLFJ_Q0ycFVmj21BOfjNN7ImOlTvDn9FvxuKaGssoRs7q4ZFk9vcdcDjJ8-F7Y2DsesTSDMSWLiWsO-nvYbEg7xPpIVlh-JCCDgu9kZF-1ALLCzTQY7tDzrcLkfpjdYo5nXyx-2qbALxfoPkO5OU8ZGKVmHk\",\"qi\":\"VUvD1nGAwzfCfRSEpZ7qy72zepyWFwWWeqOVtEwL7XWLxh7DR-p4tSTgsA3l6MkXlEDUvhuRyb14un0RUu0HdO9xSd9ynAbEMLZXu97rEOnXQ0LxIAEWQUQtMql__YlR_X0IqAaSRicJf8cdAP-lG7Rf0TZIlfVdFbqjVHkZa9g\"}";
    // 公钥
    public final static    String publicjson  = "{\"kty\":\"RSA\",\"n\":\"3O_svMpJzjAcp6vb56bXiE5g8xP1g-qssy3U11SCzWD7MxL0qx0XijUbicwRJKiozVKz1gs-E_EhFwKQPob-gRmMwJ5N6vCQcDLI7QXaZchJl9Zy_VSfFo2x5qnMVdR-AIOqMu8MROcI3z0xvZnhJGju4TI_Ka1XrUQTB_75MUxnW-bJCKubQDreLPfvqdeWkxEjsXrHB2X5JtvYgp0jz9ONuBBYm13MiShla5VgOkFNH7okg26leHKuPlPOs3MtdEbeHTOxw5qlIl7BEoXoNehk_Iu5K7hjQ5BwmV9aRG1V9B_eWfGJ3dsF2yjoevS0Fr6ckoaicIkjaisSZ5aPqQ\",\"e\":\"AQAB\"}";

    /**
     * 生成token
     * @param userId 用户id
     * @param username 用户名字
     * @return
     */
    public static String sign(Long userId,String username)  {

        try {
            // 1、 创建jwtclaims  jwt内容载荷部分
            JwtClaims claims = new JwtClaims();
            // 是谁创建了令牌并且签署了它
            claims.setIssuer("abcd");
            // 令牌将被发送给谁
            claims.setAudience("audience");
            // 失效时间长 （从现在开始10分钟）
            claims.setExpirationTimeMinutesInTheFuture(10000);
            // 令牌唯一标识符
            claims.setGeneratedJwtId();
            // 当令牌被发布或者创建现在
            claims.setIssuedAtToNow();
            // 再次之前令牌无效
            claims.setNotBeforeMinutesInThePast(2);
            // 主题
            claims.setSubject("subject");
            // 可以添加关于这个主题得声明属性
            claims.setClaim("userId",userId);
            claims.setClaim("username",username);

            // 2、签名
            JsonWebSignature jws = new JsonWebSignature();
            //赋值载荷
            jws.setPayload(claims.toJson());

            // 3、jwt使用私钥签署
            PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privatejson)).getPrivateKey();
            jws.setKey(privateKey);

            // 4、设置关键 kid
            jws.setKeyIdHeaderValue("keyId");

            // 5、设置签名算法
            jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
            // 6、生成jwt
            String jwt = jws.getCompactSerialization();

            return jwt;
        } catch (JoseException e) {
            throw new RuntimeException(e);
        }

    }


    /**
     * 解密token
     *
     * @param token
     */
    public static void checkJwt(String token) throws JoseException {

        // 1、引入公钥
        PublicKey publicKey = new RsaJsonWebKey(JsonUtil.parseJson(publicjson)).getPublicKey();

        // 2、使用jwtcoonsumer  验证和处理jwt
        JwtConsumer jwtConsumer = new JwtConsumerBuilder()
                .setRequireExpirationTime() //过期时间
                .setAllowedClockSkewInSeconds(30) //允许在验证得时候留有一些余地 计算时钟偏差  秒
                .setRequireSubject() // 主题生命
                .setExpectedIssuer("abcd") // jwt需要知道谁发布得 用来验证发布人
                .setExpectedAudience("audience") //jwt目的是谁 用来验证观众
                .setVerificationKey(publicKey) // 用公钥验证签名  验证密钥
                .setJwsAlgorithmConstraints(new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST, AlgorithmIdentifiers.RSA_USING_SHA256))
                .build();
        try {
            // 3、验证jwt 并将其处理为 claims
            JwtClaims jwtClaims = jwtConsumer.processToClaims(token);
            System.out.println(jwtClaims);
        } catch (InvalidJwtException e) {
            throw new RuntimeException(e);
        }


    }





    public static void main(String[] args) throws JoseException {

        //生成加密的秘钥
//        RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
//        //生成私钥
//        String privateKey = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
//        System.out.println(privateKey);
//        System.out.println("=========================");
//        //生成公钥
//        String publicKey = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.PUBLIC_ONLY);
//        System.out.println(publicKey);

        //TODO 登录成，得到用户账号和id

        //生成令牌
//        String token = sign(1L, "jinken");
//        System.out.println(token);

        String token = "eyJraWQiOiJrZXlJZCIsImFsZyI6IlJTMjU2In0.eyJpc3MiOiJhYmNkIiwiYXVkIjoiYXVkaWVuY2UiLCJleHAiOjE3MTg5NDg5NzQsImp0aSI6IkpGTTYzTnRTUmdXOEN5TlFMclVuZlEiLCJpYXQiOjE3MTgzNDg5NzQsIm5iZiI6MTcxODM0ODg1NCwic3ViIjoic3ViamVjdCIsInVzZXJJZCI6MSwidXNlcm5hbWUiOiJqaW5rZW4ifQ.k7I53pPRatWyk2FJHAI9m5GE1aW4Tpq0502fPZJTROsp3liUoVKUiUkub2u3XoihLapcZ5akkTMkMSkQEK48upvX5FlxG5NFQepqkKnfGFRZ7dzDqBvx5a_-TVwQq_0R2zxm6Swc3fF1Qh1EpghqSv_cfdRFLVTT0bHdMoIl3GG4ToO-ncrVTEDf5cPl2rXGNAS2JtuKoPcKcn7v47DzNIssj2kB9yhcOl-BC9DyzGA5re0xMr_KqnNVEdSQjSruEG9QhqwZlVHx9jhhSKRl8aTld-tz7GRYNvXXdm8PJ0-Mc-QIGjXNG0tnhlyIml4kbTvZf39wAiU7xhs20z1EGg";
        //校验令牌
        checkJwt(token);

    }
}
